#include <stdio.h>
#include <stdlib.h>
#include "rpcclientagent.h"
#include "os_socket.h"
#include "os.h"

RPCClientAgent::RPCClientAgent()
{
	memset(hostAddress, 0, sizeof(hostAddress));
	m_socket = 0;
	os_socket_init();
}

RPCClientAgent::~RPCClientAgent()
{

}
int RPCClientAgent::init(char *host, short port)
{
	strcpy(hostAddress, host);
	m_port = port;
	os_thread_create(RPCClientAgent::ThreadProc, this, &m_pThread);
	return 0;
}


int RPCClientAgent::ThreadProc(void *p)
{
	if (!p) {
		return -1;
	}
	RPCClientAgent *agent = (RPCClientAgent *)p;
	return agent->run();
}

int RPCClientAgent::run()
{
	m_socket = socket(AF_INET, SOCK_STREAM, 0);
	if (m_socket == INVALID_SOCKET) {
		printf("socket error\n");
		return -1;
	}

	sockaddr_in hostAddr = {0};
	hostAddr.sin_family = AF_INET;
	hostAddr.sin_port = htons(m_port);
	hostAddr.sin_addr.s_addr = inet_addr(hostAddress);
	int hostAddrLen = sizeof(hostAddr);
	if (connect(m_socket, (sockaddr *)&hostAddr, hostAddrLen) != 0) {
		printf("could not connect to server\n");
		return -1;
	}

	while (true)
	{
		char *buf = (char *)malloc(1024);
		int buf_len = 1024;
		memset(buf, 0, buf_len);
		int recved_size = 0;
		recved_size = recv(m_socket, buf, buf_len, 0);

		if (recved_size <=0) {
			printf("disconnect from server.\n");
			break;
		}

		OnDataRecieved(buf, recved_size);
	}
	
	return 0;
}


int RPCClientAgent::request_response(RPCRequest *req, char *buf, int buf_len, int ResponseTimeout)
{
	printf("enter request_response \n");
	if (os_event_create(&req->event) != 0) {
		return -1;
	}

	req->request_id = req->m_last_request_id++;

	int *header_t =  (int *)buf;
	int *header_len =  (int *)(buf +sizeof(int));
	int *ssid = (int *)(buf + sizeof(int)*2);

	*header_t = 0;
	*header_len = 4;
	*ssid = req->request_id;

	m_mapRequest[req->request_id] = req;

	if (sendData(buf, buf_len) < 0) {
		return -1;
	}

	if (os_event_wait(req->event, ResponseTimeout) != 0){
		return -1;
	}
	printf("leave request_response\n");
	
	return 0;
}
int RPCClientAgent::sendData(char *buf, int buf_len)
{
	return send(m_socket, buf, buf_len, 0);
}

int RPCClientAgent::waitForResponse(int requestid, int timeout)
{
	os_sleep(timeout);
	return 0;
}

int RPCClientAgent::OnDataRecieved(char *buf, int buf_len)
{
	printf("OnDataRecieved buf_len=%d\n", buf_len);
	int *header_t =  (int *)buf;
	int *header_len =  (int *)(buf +sizeof(int));
	int *ssid = (int *)(buf + sizeof(int)*2);

	RPCRequest *req = m_mapRequest[*ssid];
	if (req){
		req->rsp_buf = buf;
		req->rsp_buf_len = buf_len;
		os_event_set(req->event);
	}

	int FunctionType = 0;
	func_OnDataRecievedCallBack_t process_cb = m_mapOnDataRecievedCallBack[FunctionType];
	if (!process_cb) {
		return -1;
	}
	return process_cb(buf, buf_len);
}


RPCRequest::RPCRequest()
{
	rsp_buf = NULL;
	rsp_buf_len = 0;
	m_curr_arg_buf = NULL;
	m_curr_arg_buf_len = 0;
}

RPCRequest::~RPCRequest()
{

}

int RPCRequest::m_last_request_id = 0;

void RPCRequest::set_request_id(int request_id)
{
	this->request_id = request_id;
}

